using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;

public class ViewManager : MonoBehaviour
{
    [SerializeField] private List<BaseWindow> allWins;//理论上全是预制体
    [SerializeField] private Transform LayBottom;
    [SerializeField] private Transform LayCenter;
    [SerializeField] private Transform LayTop;

    private List<BaseWindow> activityWinds;
    private BaseWindow win当前窗口;


    public static ViewManager Instance=>instance;
    private static ViewManager instance;
    private void Awake()
    {
        DontDestroyOnLoad(this.gameObject);
        activityWinds = new List<BaseWindow>();
        instance = this;
    }

    private Dictionary<int, Layer> dictLayer = new Dictionary<int, Layer>();

    public void resetLayer()
    {
        dictLayer.Clear();
        var allLayer = GameObject.FindObjectsOfType<Layer>();
        foreach (var VARIABLE in allLayer)
        {
            if (dictLayer.ContainsKey(VARIABLE.Id))
            {
                dictLayer[VARIABLE.Id] = VARIABLE;
            }
            else
            {
                dictLayer.Add(VARIABLE.Id,VARIABLE);
            }
        }
    }



    public TC GetController<TC>(WinEnum id)
    {
        var win = activityWinds.FirstOrDefault(f => f.WinId == id);
        if (win == null)
        {
            //还未加载
            return OpenWindow<TC>(id);
        }
        
        TC t= win.GetController<TC>();
        return t;
    }


    public TC OpenWindow<TC>(WinEnum id)
    {
        var win = activityWinds.FirstOrDefault(f => f.WinId == id);
        if (win == null)
        {
            //还未加载
            win = InitWindow(id);
            
        }

        if (!win.gameObject.activeSelf)
        {
            win.Controller.OpenWindow();
            if (win.Enum窗口类型 == Enum窗口类型.窗口)
            {
                if (win当前窗口 != null)
                {
                    win当前窗口.Controller.CloseWindow();
                }

                win当前窗口 = win;
            }
        }

        TC t= win.GetController<TC>();
        return t;
    }


    public T GetWindow<T>(WinEnum id)
    {
        var win = activityWinds.FirstOrDefault(f => f.WinId == id);
        if (win is T s)
        {
            return s;
        }
        return default(T);
    }

    
    private BaseWindow InitWindow(WinEnum id)
    {
        var win = allWins.FirstOrDefault(f => f.WinId == id);
        if (win == null)
        {
            //没配置
            Debug.LogError($"请配置WindowManager{id}");
            return null;
        }
        
        Transform parent = GetLayParent(win.Layer);
        BaseWindow res = GameObject.Instantiate(win,parent);
        activityWinds.Add(res);
        res.Init();
        var baseControl = res.Controller;
        baseControl.InitWindow();

        return res;
    }

    private Transform GetLayParent(int id)
    {
        if (dictLayer.ContainsKey(id) && dictLayer[id]!=null)
        {
            return dictLayer[id].transform;
        }
        else
        {
            resetLayer();
            if (dictLayer.ContainsKey(id))
            {
                return dictLayer[id].transform;
            }
        }

        return null;
    }
    
    [ContextMenu("开机啊")]
    public void TestOpen()
    {
        ViewManager.Instance.OpenWindow<DemoController>(WinEnum.TestView1);
    }
}


public class BaseWindow<TV,TC> : BaseWindow where TC: BaseController,new() where TV: BaseWindow
{
    public override void Init()
    {
        // base.Init();
        controller = new TC();
        if (this is TV v)
        {
            controller.SetView(v);
        }
    }
    
}

public class BaseWindow: MonoBehaviour
{
    public WinEnum WinId;
    public Enum窗口类型 Enum窗口类型;

    protected BaseController controller;
    public virtual BaseController Controller{get{return controller;}}

    public virtual T GetController<T>()
    {
        if (controller is T t)
        {
            return t;
        }
        return default(T);
    }
    
    public int Layer;
    [SerializeField]private Enum开窗动画类型 enum开窗动画类型;
    [SerializeField]private Enum关窗动画类型 enum关窗动画类型;
    [SerializeField]private Animator animator;

    

    public virtual void Init()
    {
        controller = new BaseController();
    }


    public void OpenWindow()
    {
        gameObject.SetActive(true);
        transform.SetAsLastSibling();
        开窗动画();
    }

    public void 开窗动画()
    {
        switch (enum开窗动画类型)
        {
            case Enum开窗动画类型.无:
                return;
            // break;
            case Enum开窗动画类型.AniOpen:
            default:
                if (animator != null)
                {
                    animator.Play(enum开窗动画类型.ToString());
                }
                break;
        }
    }


    public void 关窗动画()
    {
        switch (enum关窗动画类型)
        {
            case Enum关窗动画类型.无:
                break;
            case Enum关窗动画类型.AniClose:
            default:
                if (animator != null)
                {
                    animator.Play(enum关窗动画类型.ToString());
                    return;
                }
                break;
        }
        动画结束后关窗();
    }

    public void 动画结束后关窗()
    {
        gameObject.SetActive(false);
    }
    public virtual void 开窗动画回调()
    {
        
    }

    private enum Enum开窗动画类型
    {
        无,
        AniOpen,
    }
    public enum Enum关窗动画类型
    {
        无,
        AniClose,
    }
}